package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.*;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.rooms.absrooms.AbsMultiViewRoom;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;
import java.util.*;

/**
 * 中将棋
 */
public class ChuShogiRoom extends AbsMultiViewRoom {

    List<Piece> pieceList = new ArrayList<>();
    Piece selectedTarget = null;

    boolean partialMovePhase=false;
    int partialMoveState;
    int partialMoveId;
    boolean lastMoveIsLionCapture=false;

    public ChuShogiRoom(String roomName) {
        super(roomName, "最早出现于日本室町时代的一种将棋类游戏，不同于本将棋，无打入与持驹概念，故不必设置驹台。\n某猪吹爆：杀王棋天花板，真正的战略游戏", "中将棋",
            GridsUtils.createEmptyGrids(12, 12), true, true);
    }

    @Override
    public String getRuleText() {
        return "见群文件或加群找大佬手把手教你（700377240）。\n逆界里特殊规则：无循环判定，同形复现三次判和。";
    }

    @Override
    public String getGameInfo(int view) {
        //先清空棋盘
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        pieceRender();
        if(selectedTarget!=null){
            signList.add(new AroundSign(getIndex(selectedTarget.pRow,selectedTarget.pCol), "#449F80F7", "#FF9F80F7", 1.0f));
            List<Integer> ids = new ArrayList<>();
            for(int i=0;i<curGrids.length;i++){
                for(int j=0;j<curGrids[0].length;j++){
                    if(selectedTarget.canMove(i,j)>0){
                        ids.add(getIndex(i,j));
                    }
                }
            }
            signList.add(new AroundSign(ids, "#449F80F7", "#FF9F80F7", 1.0f));
        }
        if(partialMovePhase) gameTip="请继续行动";
        else gameTip="-1";
        return super.getGameInfo(view);
    }

    private void pieceRender(){
        for(int i=0;i<curGrids.length;i++)
            for(int j=0;j<curGrids[0].length;j++)
                curGrids[i][j]=0;
        for(Piece target:pieceList){
            //System.out.println(target.mSide+" "+target.mId+" "+target.display+"~"+target.pRow+" "+target.pCol);
            curGrids[target.pRow][target.pCol]=target.mSide;
            signList.add(new TextSign(this.getIndex(target.pRow,target.pCol),target.display,target.getColor()));
        }
    }

    @Override
    protected void doStart(){
        DataManager.noticeAllGameStart(player_black, player_white, roomName);
        overFlag = 1;//重置结束状态：对弈进行中未结束
        playingStartTime = System.currentTimeMillis(); //重置对弈开始时间
        resetGrids();
        initPiece();
        selectedTarget=null;
        partialMovePhase=false;
        lastMoveIsLionCapture=false;
        noticeFirstMove();
    }

    public void noticeFirstMove() {
        noticeBlackMove();
    }

    @Override
    public void doRule(int row, int col, int value, int view) {
        selectOrMove(row, col);
        checkWin();
    }

    public void checkWin(){
        int cntKing1=0,cntTotal1=0,cntOther1=0,cntKing2=0,cntTotal2=0,cntOther2=0;
        for(Piece p:pieceList){
            if(p.mSide==1) {
                cntTotal1++;
                if (Objects.equals(p.name, "王") || Objects.equals(p.name, "+象")) cntKing1++;
                else if (!Objects.equals(p.name, "步")) cntOther1++;
            }else {
                cntTotal2++;
                if (Objects.equals(p.name, "王") || Objects.equals(p.name, "+象")) cntKing2++;
                else if (!Objects.equals(p.name, "步")) cntOther2++;
            }
        }
        if(cntKing1==0||(cntTotal1==1&&cntOther2!=0))
            doOver(WinMode.WHITE_WIN,player_white.getNickNameOrTemp()+"执后手战胜"+player_black.getNickNameOrTemp());
        if(cntKing2==0||(cntTotal2==1&&cntOther1!=0))
            doOver(WinMode.BLACK_WIN,player_black.getNickNameOrTemp()+"执先手战胜"+player_white.getNickNameOrTemp());
        //同形三次判和 doOver(WinMode.BOTH_DRAW, player_black.getNickNameOrTemp()+"执先手战平"+player_white.getNickNameOrTemp());
    }

    public Piece getPieceByPos(int row, int col) {
        for (Piece piece : pieceList)
            if (piece.pRow == row && piece.pCol == col)
                return piece;
        return null;
    }

    public void selectOrMove(int row, int col) {
        Piece target = getPieceByPos(row, col);
        if(selectedTarget==null)
            if(target==null) return; //既没有点击棋子，又没有已选中的棋子
            else if (target.mSide!=cur) return;
            else{ //选中棋子
                selectedTarget = target;
                noticeAllRefreshGameInfo();
                return ;
            }
        if (selectedTarget==target){
            if(partialMovePhase){ //放弃部分移动
                selectedTarget=null;
                partialMovePhase=false;
                noticeChangeMove();
            }else{ //取消选中
                selectedTarget=null;
                noticeAllRefreshGameInfo();
            }
            return;
        }
        int moveState;
        if(partialMovePhase) moveState=selectedTarget.canPartialMove(row,col,partialMoveState)?1:0;
        else moveState=selectedTarget.canMove(row,col); //这里已经包含了target不是友军的判断，故下面不用做了
        if(moveState==0) return; //不能走子
        //走子逻辑
        if(target!=null){
            if(Objects.equals(target.display,"狮") && !Objects.equals(selectedTarget.display,"狮"))
                if(lastMoveIsLionCapture) return ; //先狮子特殊规则
                else lastMoveIsLionCapture=true;
            else lastMoveIsLionCapture=false;
            pieceList.remove(target);
        }else lastMoveIsLionCapture=false;
        if(selectedTarget.canPromote && (((selectedTarget.mSide==1)?(selectedTarget.pCol<8&&col>7):(selectedTarget.pCol>3&&col<4)) ||
                (target!=null&&((selectedTarget.mSide==1)?(selectedTarget.pCol>7||col>7):(selectedTarget.pCol<4||col<4))) ||
                (Objects.equals(selectedTarget.name,"步") &&((selectedTarget.mSide==1&&col==11)||(selectedTarget.mSide==2&&col==0))))){
            //写给江柯：这里编辑器的警告是错的，不要根据警告把代码改了！不要根据警告把代码改了！不要根据警告把代码改了！
            selectedTarget.move(row,col);


            Player player= getCurPlayer();
            gameTip = "是否升变？";
            player.registerCustomBottom(new CustomBottom(selectedTarget.room, "升变", (p) -> {
                player.removeCustomBottom(player.findCustomBottomByTitle(selectedTarget.room, "升变"));
                player.removeCustomBottom(player.findCustomBottomByTitle(selectedTarget.room, "不升变"));
                player.dispatchCustomBottom();
                gameTip = "-1";
                selectedTarget.promote();
                changeOrPartial(target, moveState);
            }));
            player.registerCustomBottom(new CustomBottom(selectedTarget.room, "不升变", (p) -> {
                player.removeCustomBottom(player.findCustomBottomByTitle(selectedTarget.room, "升变"));
                player.removeCustomBottom(player.findCustomBottomByTitle(selectedTarget.room, "不升变"));
                player.dispatchCustomBottom();
                gameTip = "-1";
                changeOrPartial(target, moveState);
            }));
            noticeAllRefreshGameInfo();
        } else {
            selectedTarget.move(row,col);
            changeOrPartial(target, moveState);
        }
    }

    private void changeOrPartial(Piece target, int moveState) {
        if(moveState ==1){
            selectedTarget=null;
            partialMovePhase=false;
            noticeChangeMove();
        }else{
            selectedTarget= target;
            partialMovePhase=true;
            partialMoveState= moveState;
            partialMoveId=selectedTarget.mId;
        }
    }

    protected void noticeChangeMove() {
        selectedTarget=null;
        if(cur==1) noticeWhiteMove();
        else noticeBlackMove();
    }

    public boolean nonInter(int row1, int row2, int col1, int col2){
        boolean flag=true;
        if(row1==row2){ //两枚棋子在同一排
            int colS=Math.min(col1,col2),colE=Math.max(col1,col2);
            for(int j=colS+1;j<colE;j++)
                if(getPieceByPos(row1,j)!=null){
                    flag=false; break;
                }
        }else if(col1==col2){ //两枚棋子在同一列
            int rowS=Math.min(row1,row2),rowE=Math.max(row1,row2);
            for(int i=rowS+1;i<rowE;i++)
                if(getPieceByPos(i,col1)!=null){
                    flag=false; break;
                }
        }else if((row1>row2)==(col1>col2)){ //两枚棋子斜临的一种方向
            int rowS=Math.min(row1,row2),rowE=Math.max(row1,row2),colS=Math.min(col1,col2);
            for(int i=rowS+1,j=colS+1;i<rowE;i++,j++)
                if(getPieceByPos(i,j)!=null){
                    flag=false; break;
                }
        }else{ //两枚棋子斜临的另一种方向
            int rowS=Math.min(row1,row2),rowE=Math.max(row1,row2),colE=Math.max(col1,col2);
            for(int i=rowS+1,j=colE-1;i<rowE;i++,j--)
                if(getPieceByPos(i,j)!=null){
                    flag=false; break;
                }
        }
        return flag;
    }

    public abstract static class Piece {

        public ChuShogiRoom room;
        public int mSide,pRow,pCol,mId;
        public String display,name; //name是棋谱中的名字，display是显示的名字
        public boolean canPromote,promoted;
        protected int[] slideDirX,slideDirY,shiftDirX,shiftDirY;

        public Piece(ChuShogiRoom room,int mId, int mSide, int pRow,int pCol, String display, String name, boolean canPromote, boolean promoted,
                     int[] slideDirX,int[] slideDirY,int[] shiftDirX,int[] shiftDirY){
            this.room = room;
            this.mId = mId; this.mSide=mSide; this.pRow = pRow; this.pCol = pCol;
            this.display=display; this.name=name; this.canPromote=canPromote; this.promoted=promoted;
            this.slideDirX=slideDirX; this.slideDirY=slideDirY; this.shiftDirX=shiftDirX; this.shiftDirY=shiftDirY;
        }

        public void promote() {} //默认是空的，可以升变的棋子override一下它

        // CanMove这里还缺一个其它棋子吃狮子交换的判断，待写
        public int canMove(int targetRow, int targetCol){
            Piece enemy= room.getPieceByPos(targetRow,targetCol);
            if(enemy!=null && enemy.mSide==mSide) return 0;
            boolean flag=false;
            int difX=targetRow-pRow,difY=(targetCol-pCol)*(mSide==1?1:-1);
            if(shiftDirX!=null){
                for(int i=0;i<shiftDirX.length;i++)
                    if(difX==shiftDirX[i] && difY==shiftDirY[i]){
                        flag=true; break;
                    }
                if(flag) return 1;
            }
            if(slideDirX!=null){
                if(!(difX==0||difY==0||Math.abs(difX)==Math.abs(difY))) return 0;
                int divX=(difX==0)?0:(difX/Math.abs(difX)),divY=(difY==0)?0:(difY/Math.abs(difY));
                for(int i=0;i<slideDirX.length;i++){
                   if((divX==slideDirX[i]&&divY==slideDirY[i]) &&
                            (room.nonInter(pRow,targetRow,pCol,targetCol))){
                        flag=true; break;
                    }}
                if(flag) return 1;
            }
            return 0;
        }
        //返回state=0表示不可移动，1表示可移动且回合结束，>=2表示可移动且还可移动1次(需要在定义棋子时override)
        //其中2：狮子/角鹰正常的第二次移动、飞鹫左上/右下第二次移动
        //3：狮子可吃对方狮子的第二次移动、飞鹫右上/左下第二次移动 //注意中将棋协会规则补足篇的特殊情况

        public boolean canPartialMove(int targetRow, int targetCol, int state) {return false;}
        //默认是空的，狮子角鹰飞鹫把它Override一下

        protected String getColor(){return promoted?"#FFE21C1C":(mSide==1?"#FFBFE2BF":"#FF1C1C38");}
        public String info(){return String.format("%s%s-(%d,%d)",mSide==1?"黑":"白",name,pRow,pCol);}
        public void move(int row, int col){pRow=row;pCol=col;}
    }

    private void initPiece() {
        pieceList.clear();
        //兵线与仲人
        pieceList.add(new _Pawn(this,1,1,0,3)); pieceList.add(new _Pawn(this,2,1,1,3)); pieceList.add(new _Pawn(this,3,1,2,3));
        pieceList.add(new _Pawn(this,4,1,3,3)); pieceList.add(new _Pawn(this,5,1,4,3)); pieceList.add(new _Pawn(this,6,1,5,3));
        pieceList.add(new _Pawn(this,7,1,6,3)); pieceList.add(new _Pawn(this,8,1,7,3)); pieceList.add(new _Pawn(this,9,1,8,3));
        pieceList.add(new _Pawn(this,10,1,9,3)); pieceList.add(new _Pawn(this,11,1,10,3)); pieceList.add(new _Pawn(this,12,1,11,3));
        pieceList.add(new _Pawn(this,13,2,0,8)); pieceList.add(new _Pawn(this,14,2,1,8)); pieceList.add(new _Pawn(this,15,2,2,8));
        pieceList.add(new _Pawn(this,16,2,3,8)); pieceList.add(new _Pawn(this,17,2,4,8)); pieceList.add(new _Pawn(this,18,2,5,8));
        pieceList.add(new _Pawn(this,19,2,6,8)); pieceList.add(new _Pawn(this,20,2,7,8)); pieceList.add(new _Pawn(this,21,2,8,8));
        pieceList.add(new _Pawn(this,22,2,9,8)); pieceList.add(new _Pawn(this,23,2,10,8)); pieceList.add(new _Pawn(this,24,2,11,8));
        pieceList.add(new _GBetween(this,25,1,3,4)); pieceList.add(new _GBetween(this,26,1,8,4));
        pieceList.add(new _GBetween(this,27,2,3,7)); pieceList.add(new _GBetween(this,28,2,8,7));
        //底线棋驹
        pieceList.add(new _Lance(this,29,1,0,0)); pieceList.add(new _Lance(this,30,1,11,0));
        pieceList.add(new _Lance(this,31,2,0,11)); pieceList.add(new _Lance(this,32,2,11,11));
        pieceList.add(new _FLeopard(this,33,1,1,0)); pieceList.add(new _FLeopard(this,34,1,10,0));
        pieceList.add(new _FLeopard(this,35,2,1,11)); pieceList.add(new _FLeopard(this,36,2,10,11));
        pieceList.add(new _CopperG(this,37,1,2,0)); pieceList.add(new _CopperG(this,38,1,9,0));
        pieceList.add(new _CopperG(this,39,2,2,11)); pieceList.add(new _CopperG(this,40,2,9,11));
        pieceList.add(new _SilverG(this,41,1,3,0)); pieceList.add(new _SilverG(this,42,1,8,0));
        pieceList.add(new _SilverG(this,43,2,3,11)); pieceList.add(new _SilverG(this,44,2,8,11));
        pieceList.add(new _GoldG(this,45,1,4,0)); pieceList.add(new _GoldG(this,46,1,7,0));
        pieceList.add(new _GoldG(this,47,2,4,11)); pieceList.add(new _GoldG(this,48,2,7,11));
        pieceList.add(new _DElephant(this,49,1,6,0)); pieceList.add(new _DElephant(this,50,2,5,11));
        pieceList.add(new _King(this,51,1,5,0)); pieceList.add(new _King(this,52,2,6,11));
        //二三线无狮子步棋驹
        pieceList.add(new _ReverseC(this,53,1,0,1)); pieceList.add(new _ReverseC(this,54,1,11,1));
        pieceList.add(new _ReverseC(this,55,2,0,10)); pieceList.add(new _ReverseC(this,56,2,11,10));
        pieceList.add(new _Bishop(this,57,1,2,1)); pieceList.add(new _Bishop(this,58,1,9,1));
        pieceList.add(new _Bishop(this,59,2,2,10)); pieceList.add(new _Bishop(this,60,2,9,10));
        pieceList.add(new _BTiger(this,61,1,4,1)); pieceList.add(new _BTiger(this,62,1,7,1));
        pieceList.add(new _BTiger(this,63,2,4,10)); pieceList.add(new _BTiger(this,64,2,7,10));
        pieceList.add(new _Phoenix(this,65,1,6,1)); pieceList.add(new _Phoenix(this,66,2,5,10));
        pieceList.add(new _SideM(this,67,1,0,2)); pieceList.add(new _SideM(this,68,1,11,2));
        pieceList.add(new _SideM(this,69,2,0,9)); pieceList.add(new _SideM(this,70,2,11,9));
        pieceList.add(new _VerticalM(this,71,1,1,2)); pieceList.add(new _VerticalM(this,72,1,10,2));
        pieceList.add(new _VerticalM(this,73,2,1,9)); pieceList.add(new _VerticalM(this,74,2,10,9));
        pieceList.add(new _Rook(this,75,1,2,2)); pieceList.add(new _Rook(this,76,1,9,2));
        pieceList.add(new _Rook(this,77,2,2,9)); pieceList.add(new _Rook(this,78,2,9,9));
        pieceList.add(new _FreeK(this,79,1,6,2)); pieceList.add(new _FreeK(this,80,2,5,9));
        //含狮子步棋驹(麒麟 狮子 龙王 龙马)
        pieceList.add(new _Kylin(this,81,1,5,1)); pieceList.add(new _Kylin(this,82,2,6,10));
        pieceList.add(new _DHorse(this,83,1,3,2)); pieceList.add(new _DHorse(this,84,1,8,2));
        pieceList.add(new _DHorse(this,85,2,3,9)); pieceList.add(new _DHorse(this,86,2,8,9));
        pieceList.add(new _DragonK(this,87,1,4,2)); pieceList.add(new _DragonK(this,88,1,7,2));
        pieceList.add(new _DragonK(this,89,2,4,9)); pieceList.add(new _DragonK(this,90,2,7,9));
        pieceList.add(new _Lion(this,91,1,5,2)); pieceList.add(new _Lion(this,92,2,6,9));

    }
    //棋子的走法

    private static class _Pawn extends Piece {
        public _Pawn(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"步","步",true,false,
                null,null,new int[]{0},new int[]{1});}
        @Override
        public void promote(){
            room.pieceList.add(new _PawnP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _PawnP extends Piece {
        public _PawnP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"と","と",false,true,
                null,null,new int[]{0,0,-1,-1,1,1},new int[]{1,-1,1,0,1,0});}
    }
    private static class _GBetween extends Piece {
        public _GBetween(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"仲","仲",true,false,
                null,null,new int[]{0,0},new int[]{1,-1});}
        @Override
        public void promote(){
            room.pieceList.add(new _GBetweenP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _GBetweenP extends Piece {
        public _GBetweenP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"象","+仲",false, true,
                null,null,new int[]{0,-1,-1,-1,1,1,1},new int[]{1,-1,0,1,-1,0,1});}
    }

    private static class _Lance extends Piece {
        public _Lance(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"香","香",true,false,
                new int[]{0},new int[]{1},null,null);}
        @Override
        public void promote(){
            room.pieceList.add(new _LanceP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _LanceP extends Piece {
        public _LanceP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col, "驹","+香",false,true,
                new int[]{0,0,-1,1},new int[]{1,-1,1,1},null,null);}
    }
    private static class _FLeopard extends Piece {
        public _FLeopard(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"豹","豹",true,false,
                null,null,new int[]{0,0,-1,-1,1,1},new int[]{1,-1,1,-1,1,-1});}
        @Override
        public void promote(){
            room.pieceList.add(new _FLeopardP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _FLeopardP extends Piece {
        public _FLeopardP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"角","+豹",false,true,
                new int[]{1,1,-1,-1},new int[]{1,-1,1,-1},null,null);}
    }
    private static class _CopperG extends Piece {
        public _CopperG(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"铜","铜",true,false,
                null,null,new int[]{0,0,-1,1},new int[]{1,-1,1,1});}
        @Override
        public void promote(){
            room.pieceList.add(new _CopperGP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _CopperGP extends Piece {
        public _CopperGP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"横","+铜",false,true,
                new int[]{1,-1},new int[]{0,0},new int[]{0,0},new int[]{1,-1});}
    }
    private static class _SilverG extends Piece {
        public _SilverG(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"银","银",true,false,
                null,null,new int[]{0,-1,-1,1,1},new int[]{1,-1,1,-1,1});}
        @Override
        public void promote(){
            room.pieceList.add(new _SilverGP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _SilverGP extends Piece {
        public _SilverGP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"竖","+银",false,true,
                new int[]{0,0},new int[]{1,-1},new int[]{1,-1},new int[]{0,0});}
    }
    private static class _GoldG extends Piece {
        public _GoldG(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"金","金",true,false,
                null,null,new int[]{0,0,-1,-1,1,1},new int[]{-1,1,0,1,0,1});}
        @Override
        public void promote(){
            room.pieceList.add(new _GoldGP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _GoldGP extends Piece {
        public _GoldGP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"飞","+金",false,true,
                new int[]{0,0,1,-1},new int[]{1,-1,0,0},null,null);}
    }
    private static class _DElephant extends Piece {
        public _DElephant(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"象","象",true,false,
                null,null,new int[]{0,-1,-1,-1,1,1,1},new int[]{1,-1,0,1,-1,0,1});}
        @Override
        public void promote(){
            room.pieceList.add(new _DElephantP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _DElephantP extends Piece {
        public _DElephantP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"太","+象",false,true,
                null,null,new int[]{0,0,-1,-1,-1,1,1,1},new int[]{-1,1,-1,0,1,-1,0,1});}
    }
    private static class _King extends Piece {
        public _King(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"王","王",false,false,
                null,null,new int[]{0,0,-1,-1,-1,1,1,1},new int[]{-1,1,-1,0,1,-1,0,1});}
    }

    private static class _ReverseC extends Piece {
        public _ReverseC(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"反","反",true,false,
                new int[]{0,0},new int[]{1,-1},null,null);}
        @Override
        public void promote(){
            room.pieceList.add(new _ReverseCP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _ReverseCP extends Piece {
        public _ReverseCP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col, "鲵","+反",false,true,
                new int[]{0,0,-1,1},new int[]{1,-1,-1,-1},null,null);}
    }
    private static class _Bishop extends Piece {
        public _Bishop(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"角","角",true,false,
                new int[]{-1,1,-1,1},new int[]{1,1,-1,-1},null,null);}
        @Override
        public void promote(){
            room.pieceList.add(new _BishopP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _BishopP extends Piece {
        public _BishopP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"马","+角",false,true,
                new int[]{-1,1,-1,1},new int[]{1,1,-1,-1},new int[]{0,0,-1,1},new int[]{-1,1,0,0});}
    }
    private static class _BTiger extends Piece {
        public _BTiger(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"虎","虎",true,false,
                null,null,new int[]{0,-1,-1,-1,1,1,1},new int[]{-1,-1,0,1,-1,0,1});}
        @Override
        public void promote(){
            room.pieceList.add(new _BTigerP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _BTigerP extends Piece {
        public _BTigerP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"鹿","+虎",false,true,
                new int[]{-1,-1,-1,1,1,1},new int[]{-1,0,1,-1,0,1},new int[]{0,0},new int[]{1,-1});}
    }
    private static class _Phoenix extends Piece {
        public _Phoenix(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"凤","凤",true,false,
                null,null,new int[]{-2,-2,-1,0,0,1,2,2},new int[]{-2,2,0,-1,1,0,-2,2});}
        @Override
        public void promote(){
            room.pieceList.add(new _PhoenixP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _PhoenixP extends Piece {
        public _PhoenixP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"奔","+凤",false,true,
                new int[]{0,0,-1,-1,-1,1,1,1},new int[]{-1,1,-1,0,1,-1,0,1},null,null);}
    }
    private static class _Kylin extends Piece {
        public _Kylin(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"麒","麒",true,false,
                null,null,new int[]{-2,-1,-1,0,0,1,1,2},new int[]{0,-1,1,-2,2,-1,1,0});}
        @Override
        public void promote(){
            room.pieceList.add(new _KylinP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }

    private static class _SideM extends Piece {
        public _SideM(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"横","横",true,false,
                new int[]{1,-1},new int[]{0,0},new int[]{0,0},new int[]{1,-1});}
        @Override
        public void promote(){
            room.pieceList.add(new _SideMP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _SideMP extends Piece {
        public _SideMP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"猪","+横",false,true,
                new int[]{-1,-1,-1,1,1,1},new int[]{-1,0,1,-1,0,1},null,null);}
    }
    private static class _VerticalM extends Piece {
        public _VerticalM(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"竖","竖",true,false,
                new int[]{0,0},new int[]{-1,1},new int[]{-1,1},new int[]{0,0});}
        @Override
        public void promote(){
            room.pieceList.add(new _VerticalMP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _VerticalMP extends Piece {
        public _VerticalMP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"牛","+竖",false,true,
                new int[]{-1,-1,0,0,1,1},new int[]{-1,1,-1,1,-1,1},null,null);}
    }
    private static class _Rook extends Piece {
        public _Rook(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"飞","飞",true,false,
                new int[]{-1,1,0,0},new int[]{0,0,-1,1},null,null);}
        @Override
        public void promote(){
            room.pieceList.add(new _RookP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _RookP extends Piece {
        public _RookP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"龙","+飞",false,true,
                new int[]{-1,1,0,0},new int[]{0,0,-1,1},new int[]{-1,-1,1,1},new int[]{-1,1,-1,1});}
    }
    private static class _DHorse extends Piece {
        public _DHorse(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"马","马",true,false,
                new int[]{-1,1,-1,1},new int[]{1,1,-1,-1},new int[]{0,0,-1,1},new int[]{-1,1,0,0});}
        @Override
        public void promote(){
            room.pieceList.add(new _DHorseP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _DragonK extends Piece {
        public _DragonK(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"龙","龙",true,false,
                new int[]{-1,1,0,0},new int[]{0,0,-1,1},new int[]{-1,-1,1,1},new int[]{-1,1,-1,1});}
        @Override
        public void promote(){
            room.pieceList.add(new _DragonKP(room,this.mId,mSide,pRow,pCol));
            room.pieceList.remove(this);
        }
    }
    private static class _FreeK extends Piece {
        public _FreeK(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"奔","奔",false,false,
                new int[]{0,0,-1,-1,-1,1,1,1},new int[]{-1,1,-1,0,1,-1,0,1},null,null);}
    }

    //以下是含有狮子步的棋子，还没有写
    private static class _KylinP extends Piece {
        public _KylinP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"狮","+麒",false,true,
                null,null,null,null);}
        @Override
        public int canMove(int targetRow, int targetCol){
            int distance=Math.max(Math.abs(pRow-targetRow),Math.abs(pCol-targetCol));
            if(distance>2||distance==0) return 0;
            if(distance==2) /*判断狮子吃狮子的特殊情况*/ return 1;
            if(distance==1) /*partialMove相关*/ return 2;
            return 0;
        }
        @Override
        public boolean canPartialMove(int targetRow, int targetCol, int state){
            return false;
        }
    }
    private static class _Lion extends Piece{
        public _Lion(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"狮","狮",false,false,
                null,null,new int[]{-2,-2,-2,-2,-2,-1,-1,0,0,1,1,2,2,2,2,2},
                new int[]{-2,-1,0,1,2,-2,2,-2,2,-2,2,-2,-1,0,1,2});}
        @Override
        public int canMove(int targetRow, int targetCol){
            //这里想办法不要复制麒麟的代码，而是直接复用，方便后续改变bug
            return 0;
        }
        @Override
        public boolean canPartialMove(int targetRow, int targetCol, int state){
            return false;
        }
    }
    private static class _DHorseP extends Piece {
        public _DHorseP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"鹰","+马",false,true,
                new int[]{-1,-1,-1,0,1,1,1},new int[]{-1,0,1,-1,-1,0,1},new int[]{0},new int[]{2});}
        public int canMove(int targetRow, int targetCol){
            if(targetRow==pRow&&((mSide==1&&targetCol==pCol+1)||(mSide==2&&targetCol==pCol-1))){
                if(room.getPieceByPos(targetRow,targetCol)==null) return 2;
                if(room.getPieceByPos(targetRow,targetCol).mSide!=mSide) return 2;
            }
            return super.canMove(targetRow,targetCol);
        }
        @Override
        public boolean canPartialMove(int targetRow, int targetCol, int state){
            if(state==2){ //应该是不需要这个判断，为了加个容错
                return targetRow==pRow&&Math.abs(targetCol-pCol)==1;
            }else return false;
        }
    }
    private static class _DragonKP extends Piece {
        public _DragonKP(ChuShogiRoom room,int myId, int side, int row, int col){super(room,myId,side,row,col,"鹫","+龙",false,true,
                new int[]{-1,-1,0,0,1,1},new int[]{-1,0,-1,1,-1,0},new int[]{-2,2},new int[]{2,2});}
        public int canMove(int targetRow, int targetCol){
            if(Math.abs(targetRow-pRow)==1 &&
               ((mSide==1&&targetCol==pCol+1)||(mSide==2&&targetCol==pCol-1))){
                if(room.getPieceByPos(targetRow,targetCol)==null) return (targetRow>pRow)?2:3;
                if(room.getPieceByPos(targetRow,targetCol).mSide!=mSide) return (targetRow>pRow)?2:3;
            }
            return super.canMove(targetRow,targetCol);
        }
        @Override
        public boolean canPartialMove(int targetRow, int targetCol, int state){
            if(state==2){ //应该是不需要这个判断，为了加个容错
                return Math.abs(targetRow-pRow)==1&&(targetRow-pRow)==(targetCol-pCol);
            }else if(state==3){
                return Math.abs(targetRow-pRow)==1&&(targetRow-pRow)==(-targetCol+pCol);
            }else return false;
        }
    }

}

/* TODO:
    [V] 0.partialMove的系统，以及角鹰飞鹫的狮子步走法
    [V] 1.先狮子的规则加在selectOrMove里，搞个全局变量就行
    2.修BUG:升变后客户端崩溃；弹框选择是否升变
    *.行列反了的问题给修好
    3.狮子、麒麟的走法，包括狮子吃狮子的判定，注意第三条和第五条的实现
    4.全局三次同形复现判和
    5.棋谱记录，与lishogi统一格式，从而可以借用lishogi的回放来用
    6.测试发现BUG改BUG测试发现BUG改BUG测试发现BUG改BUG
 */
